﻿using DoNet.Common.Helpers;
using DoNet.Common.Result;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Security.Claims;
using System.Collections.Specialized;
using System.Reflection;
using System.Web;

namespace WechatMp.Web.Controllers.API
{
    /// <summary>
    /// WebApi控制器基类
    /// </summary>
    [ApiController]
    public class ApiController : Controller
    {
        #region 重写基类在Action执行之前的事情
        /// <summary>
        /// 重写基类在Action执行之前的事情
        /// 根据token获得当前用户，允许匿名的不需要获取用户
        /// </summary>
        /// <param name="context">重写方法的参数</param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                //匿名访问，不需要token认证、签名和登录
                var allowanyone = controllerActionDescriptor?.MethodInfo.GetCustomAttribute(typeof(AllowAnonymousAttribute), true);
                if (allowanyone == null)
                {
                    CommonResult result = new CommonResult();
                    var request = context.HttpContext.Request;
                    var requestHeaders = request.Headers;
                    //需要token认证
                    string authHeader = requestHeaders["Authorization"].ToString();//Header中的token
                    if (!string.IsNullOrEmpty(authHeader))
                    {
                        string token = string.Empty;
                        if (authHeader.Length > 7)
                        {
                            token = authHeader.Substring(7);
                        }
                        TokenProvider tokenProvider = new TokenProvider();
                        var validateToken = tokenProvider.ValidateToken(token);
                        // token验证失败
                        if (validateToken.Success)
                        {
                            #region 签名验证
                            var signHeader = requestHeaders["sign"].SingleOrDefault() ?? string.Empty;
                            bool boolSign = string.IsNullOrWhiteSpace(signHeader) ? false : true;
                            var isSign = controllerActionDescriptor?.MethodInfo.GetCustomAttribute(typeof(NoSignRequiredAttribute), true);
                            //需要签名验证
                            if (isSign == null && boolSign)
                            {
                                string appId = requestHeaders["appId"].SingleOrDefault() ?? string.Empty;
                                string appSecret = "";
                                string nonce = requestHeaders["nonce"].SingleOrDefault() ?? string.Empty;
                                long timeStamp;
                                if (!long.TryParse(requestHeaders["timeStamp"].SingleOrDefault(), out timeStamp))
                                {
                                    timeStamp = default;
                                }
                                string signature = requestHeaders["signature"].SingleOrDefault() ?? string.Empty;

                                NameValueCollection form = HttpUtility.ParseQueryString(request.QueryString.ToString());
                                var data = string.Empty;
                                if (form.Count > 0)
                                {
                                    data = SignHelper.GetQueryString(form);
                                }
                                else
                                {
                                    using (Stream stream = request.Body)
                                    {
                                        using (StreamReader streamReader = new StreamReader(stream))
                                        {
                                            data = streamReader.ReadToEndAsync().Result;
                                        }
                                    }
                                }
                                var resultSign = SignHelper.CheckSign(appId, appSecret, nonce, timeStamp, signature, data);
                                if (!resultSign.Success)
                                {
                                    context.Result = new JsonResult(resultSign);
                                    return;
                                }
                            }
                            #endregion

                            //#region 是否需要验证用户登录以及相关的功能权限
                            ////是否需要用户登录
                            //var isDefined = controllerActionDescriptor?.MethodInfo.GetCustomAttribute(typeof(NoPermissionRequiredAttribute));
                            ////不需要登录
                            //if (isDefined != null) return;
                            ////需要登录和验证功能权限
                            //if (result.ResData != null)
                            //{
                            //    var claimlist = result.ResData as List<Claim>;
                            //    if (claimlist != null && claimlist.Count > 0)
                            //    {
                            //        string userId = EncodeHelper.AES_Decrypt(claimlist[3].Value);
                            //        string account = EncodeHelper.AES_Decrypt(claimlist[2].Value);
                            //        string role = EncodeHelper.AES_Decrypt(claimlist[4].Value);

                            //        CurrentUser user = new CurrentUser
                            //        {
                            //            UserId = Convert.ToInt64(claimlist[3].Value),
                            //            Account = claimlist[2].Value,
                            //            Role = claimlist[4].Value
                            //        };

                            //        var claims = new[] {
                            //            new Claim(ClaimConst.UserId, userId),
                            //            new Claim(ClaimConst.UserName, account),
                            //            new Claim(ClaimConst.Role, role)
                            //        };
                            //        var identity = new ClaimsIdentity(claims);
                            //        var principal = new ClaimsPrincipal(identity);
                            //        context.HttpContext.User = principal;
                            //        bool isAdmin = Permission.IsAdmin(user);
                            //        if (!isAdmin)
                            //        {
                            //            var authorizeAttribute = controllerActionDescriptor?.MethodInfo.GetCustomAttributes(typeof(CustomerAuthorizeAttribute), true).OfType<CustomerAuthorizeAttribute>().FirstOrDefault();
                            //            if (authorizeAttribute != null)
                            //            {
                            //                string function = authorizeAttribute.Function;
                            //                if (!string.IsNullOrEmpty(function))
                            //                {
                            //                    string functionCode = controllerActionDescriptor?.ControllerName + "/" + function;
                            //                    bool bl = Permission.HasFunction(functionCode, userId);
                            //                    if (!bl)
                            //                    {
                            //                        result.ErrCode = "403";
                            //                        result.ErrMsg = "您未被授权使用该功能，请重新登录试试或联系系统管理员进行处理";
                            //                        context.Result = new JsonResult(result);
                            //                    }
                            //                }
                            //            }
                            //        }
                            //        return;
                            //    }
                            //}
                            //else
                            //{
                            //    result.ErrCode = "40008";
                            //    result.ErrMsg = "用户未登录或超时";
                            //    context.Result = new JsonResult(result);
                            //}
                            //#endregion
                        }
                        else
                        {
                            context.Result = new JsonResult(result);
                        }
                    }
                    else
                    {
                        result.ErrCode = "40004";
                        result.ErrMsg = "不合法的凭证";
                        context.Result = new JsonResult(result);
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                var error = ex.ToString();
            }
        }
        #endregion 重写基类在Action执行之前的事情

        /// <summary>
        /// 把object对象转换为ContentResult
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        protected IActionResult ToJsonContent(object obj)
        {
            return Content(JsonHelper.SerializeObject(obj));
        }
    }
}
